package ${servicePackageName}.impl;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fw.cost.commons.excel.ImportUtils;
import com.fw.cost.commons.utils.FiscalYearUtils;
import com.fw.cost.model.exception.BaseBusinessException;
import com.fw.cost.model.exception.MessageUtils;
import com.fw.cost.model.form.BussResultForm;
import com.fw.cost.model.form.basic.BasicCopyPreviousPeriodForm;
import com.fw.cost.model.form.basic.BasicImportForm;
import com.fw.cost.commons.utils.UUIDUtils;
import ${entityPackageName}.${classInfo.classAliasName}Model;
import ${servicePackageName}.I${classInfo.classAliasName}Service;
import ${mapperPackageName}.I${classInfo.classAliasName}Mapper;
import ${formPackageName}.*;
import com.fw.cost.producer.service.fiscalYear.IFiscalYearService;
import com.fw.cost.model.metadata.ApiPageResult;
import com.fw.cost.model.util.enums.ImportModuleEnum;
import com.fw.cost.model.vo.costCollection.AnalyzeImportResultVo;
import com.fw.cost.model.vo.fiscalYear.FiscalYearSimpleVo;
import com.fw.cost.producer.config.AsyncImportHelper;
import com.google.common.collect.Maps;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
* <b><code></code></b>
* <p/>
*
* ${classInfo.classComment}
*
* <p/>
* <b>Creation Time:</b> ${.now?string('yyyy/MM/dd HH:mm:ss')}
*
* @author ${classInfo.authorName}
* @version ${classInfo.version}
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class ${classInfo.classAliasName}ServiceImpl extends ServiceImpl<I${classInfo.classAliasName}Mapper,${classInfo.classAliasName}Model> implements I${classInfo.classAliasName}Service {

private final IFiscalYearService fiscalYearService;

    /**
    * 获取${classInfo.classComment}列表
    *
    * @param queryForm
    * @return ApiPageResult
    * @Date ${.now?string('yyyy/MM/dd HH:mm:ss')}
    * @since ${classInfo.version}
    */
    @Override
    public ApiPageResult get${classInfo.classAliasName}List(${classInfo.classAliasName}QueryForm queryForm) {
        IPage<${classInfo.classAliasName}Model> page = new Page<>(queryForm.getPageNo(), queryForm.getLimit());
        LambdaQueryWrapper<${classInfo.classAliasName}Model> queryWrapper = Wrappers.lambdaQuery(${classInfo.classAliasName}Model.class); 
        IPage<${classInfo.classAliasName}Model> listPage = this.page(page, queryWrapper); 
        return new ApiPageResult(listPage.getCurrent(), listPage.getSize(), listPage.getTotal(), listPage.getRecords());
    }


    /**
    * 新增、更新${classInfo.classComment}
    *
    * @param addForm
    * @return void
    * @Date ${.now?string('yyyy/MM/dd HH:mm:ss')}
    * @since ${classInfo.version}
    */
    @Override
    public void addOrUpdate${classInfo.classAliasName}(${classInfo.classAliasName}AddForm addForm) { 
            
    }
            

    /**
    * 通过主键ID列表删除
    *
    * @param idList
    * @param period
    * @return void
    * @Date ${.now?string('yyyy/MM/dd HH:mm:ss')}
    * @since ${classInfo.version}
    */
    @Override
    public void delBy${classInfo.classAliasName}List(List<String> idList, String period) {      
                
    }

    /**
    * 导入分析
    *
    * @param basicImportForm
    * @param importList
    * @return AnalyzeImportResultVo
    * @Date ${.now?string('yyyy/MM/dd HH:mm:ss')}
    * @since ${classInfo.version}
    */
    @Override
    public AnalyzeImportResultVo importAnalysis(BasicImportForm basicImportForm, List<${classInfo.classAliasName}ImportExcelForm> importList) {
        AnalyzeImportResultVo analyzeImportResultVo = new AnalyzeImportResultVo();
    
        //导入总数
        Integer total = CollectionUtil.isEmpty(importList) ? 0 : importList.size();
        analyzeImportResultVo.setTotal(total);
    
        //表头
        Map<String, String> headMap = Maps.newLinkedHashMap();
                    
        headMap.put("errorMsg", "失败原因");
        analyzeImportResultVo.setHeadTab(headMap);
    
        //成功数据
        List<Map<String, Object>> successData = new ArrayList<>();
        //错误数据
        List<Map<String, Object>> errorData = new ArrayList<>();
        //所有数据
        List<List<Object>> resultList = new ArrayList<>();
    
        //会计期间
        String period = basicImportForm.getPeriod();
        String fiscalYear = FiscalYearUtils.getFiscalYear(period);
        Integer accountingPeriod = FiscalYearUtils.getAccountingPeriod(period);
        Map<String, ${classInfo.classAliasName}Model> map = getConvertMap${classInfo.classAliasName}Map(fiscalYear, accountingPeriod);
    
        //导入模式
        Integer importMode = basicImportForm.getImportMode();
    
        //导入解析处理
        importParseCallback(importMode, importList, map, (importExcelForm, errorMsg) -> {
            if (StrUtil.isNotBlank(errorMsg)) {
                //编码不符合规则
                Map<String, Object> errorMap = BeanUtil.beanToMap(importExcelForm);
                errorMap.put("errorMsg", errorMsg);
                resultList.add(ImportUtils.convertMapToListOfLists(errorMap));
                errorData.add(errorMap);
            } else {
                Map<String, Object> successDataMap = BeanUtil.beanToMap(importExcelForm);
                successData.add(successDataMap);
            }
            });
    
            //结果
            analyzeImportResultVo.setSuccessNum(successData.size());
            analyzeImportResultVo.setErrorNum(errorData.size());
            analyzeImportResultVo.setSuccessData(successData);
            analyzeImportResultVo.setErrorData(errorData);
    
            //构建导入分析结果文件所需参数
            List<List<String>> heads = getImportHead();
            String resultFile = ImportUtils.saveImportAnalysisFile(ImportModuleEnum.INCOME_PROJECT_RESULT, heads, resultList);
            analyzeImportResultVo.setFileUrl(resultFile);
            return analyzeImportResultVo;
    }


    /**
    * 导入${classInfo.classComment}
    *
    * @param basicImportForm
    * @param importList
    * @return void
    * @Date ${.now?string('yyyy/MM/dd HH:mm:ss')}
    * @since ${classInfo.version}
    */
    @Override
    public void import${classInfo.classAliasName}(BasicImportForm basicImportForm, List<${classInfo.classAliasName}ImportExcelForm> importList) {
        //会计期间
        String period = basicImportForm.getPeriod();
        String fiscalYear = FiscalYearUtils.getFiscalYear(period);
        Integer accountingPeriod = FiscalYearUtils.getAccountingPeriod(period);
    
        //记录日志
        String logId = insertOperatorLog(fiscalYear, accountingPeriod);
    
        AsyncImportHelper.syncImport(() -> {
       
        }, logId);
   }
                                
                                

    /**
    * 检查上一个周期的会计周期
    *
    * @param basicCopyPreviousPeriodForm
    * @return BussResultForm
    * @Date 9:21 2024/8/15
    * @since ${classInfo.version}
    */
    @Override
    public BussResultForm checkCopyLastFiscalYearData(BasicCopyPreviousPeriodForm basicCopyPreviousPeriodForm) {
        BussResultForm bussResultForm = new BussResultForm();

        //为空校验
        if (basicCopyPreviousPeriodForm == null) {
            bussResultForm.setCode(BussResultForm.UNABLE_TO_CONTINUE);
            bussResultForm.setMsg(MessageUtils.get("参数为空"));
            return bussResultForm;
        }

        //会计周期为空
        String period = basicCopyPreviousPeriodForm.getPeriod();
        if (StrUtil.isBlank(period)) {
            bussResultForm.setCode(BussResultForm.UNABLE_TO_CONTINUE);
            bussResultForm.setMsg(MessageUtils.get("请选择会计周期"));
            return bussResultForm;
        }
    
        //上一周期暂无该数据
        String fiscalYear = FiscalYearUtils.getFiscalYear(period);
        Integer accountingPeriod = FiscalYearUtils.getAccountingPeriod(period);
        //获取上一期间
        FiscalYearSimpleVo lastAccountingPeriod = fiscalYearService.getLastAccountingPeriod(fiscalYear, accountingPeriod);
        if (lastAccountingPeriod == null) {
            bussResultForm.setCode(BussResultForm.UNABLE_TO_CONTINUE);
            bussResultForm.setMsg(String.format("【%s年%d月】获取不到上一周期，无法复制，可以通过新增方式添加数据",fiscalYear,accountingPeriod));
            return bussResultForm;
        }


        //上期间数据
        LambdaQueryWrapper<${classInfo.classAliasName}Model> lastAccountingPeriodWrapper = Wrappers.lambdaQuery(${classInfo.classAliasName}Model.class);
        lastAccountingPeriodWrapper
            .eq(${classInfo.classAliasName}Model::getFiscalYear, lastAccountingPeriod.getFiscalYear())
            .eq(${classInfo.classAliasName}Model::getAccountingPeriod, lastAccountingPeriod.getAccountingPeriod());
        Integer lastAccountingPeriodCount = getBaseMapper().selectCount(lastAccountingPeriodWrapper);
        if (lastAccountingPeriodCount == 0) {
            bussResultForm.setCode(BussResultForm.UNABLE_TO_CONTINUE);
            bussResultForm.setMsg(String.format("上一周期【%s年%d月】暂无该数据，无法复制，可以通过新增方式添加数据",lastAccountingPeriod.getFiscalYear(),lastAccountingPeriod.getAccountingPeriod()));
            return bussResultForm;
        }
    
        //本期间数据
        LambdaQueryWrapper<${classInfo.classAliasName}Model> currentAccountingPeriodWrapper = Wrappers.lambdaQuery(${classInfo.classAliasName}Model.class);
        currentAccountingPeriodWrapper
                .eq(${classInfo.classAliasName}Model::getFiscalYear, fiscalYear)
                .eq(${classInfo.classAliasName}Model::getAccountingPeriod, accountingPeriod);
        Integer currentAccountingPeriodCount = getBaseMapper().selectCount(currentAccountingPeriodWrapper);
        if (currentAccountingPeriodCount == 0) {
            bussResultForm.setCode(BussResultForm.CAN_CONTINUE);
            bussResultForm.setMsg(String.format("确定要复制上一周期【%s年%d月】的数据吗？",lastAccountingPeriod.getFiscalYear(),lastAccountingPeriod.getAccountingPeriod()));
            return bussResultForm;
        }
    
        if (currentAccountingPeriodCount > 0) {
            bussResultForm.setCode(BussResultForm.CAN_CONTINUE);
            bussResultForm.setMsg(String.format("当前周期【%s年%d月】已存在数据，是否覆盖？",fiscalYear,accountingPeriod));
            return bussResultForm;
        }
                                            
                                            
        bussResultForm.setCode(BussResultForm.SUCCESS);
        return bussResultForm;
    }
                                        
                                        

    /**
    * 复制上一个会计周期
    *
    * @param basicCopyPreviousPeriodForm
    * @return void
    * @Date 9:22 2024/8/15
    * @since ${classInfo.version}
    */
    @Override
    public void copyPreviousPeriod(BasicCopyPreviousPeriodForm basicCopyPreviousPeriodForm) {
        if(basicCopyPreviousPeriodForm == null ){
            throw new BaseBusinessException("参数为空");
        }
    
        //会计周期为空
        String period = basicCopyPreviousPeriodForm.getPeriod();
        if(StrUtil.isBlank(period)){
             throw new BaseBusinessException("请选择会计周期");
        }
    
        //上一成本周期不存在
        String fiscalYear = FiscalYearUtils.getFiscalYear(period);
        Integer accountingPeriod = FiscalYearUtils.getAccountingPeriod(period);
        FiscalYearSimpleVo lastAccountingPeriod = fiscalYearService.getLastAccountingPeriod(fiscalYear, accountingPeriod);
        if(lastAccountingPeriod == null){
            throw new BaseBusinessException("上一成本周期不存在");
        }

        //上一周期暂无数据
        LambdaQueryWrapper<${classInfo.classAliasName}Model> wrapper = Wrappers.lambdaQuery(${classInfo.classAliasName}Model.class);
            wrapper
            .eq(${classInfo.classAliasName}Model::getFiscalYear,lastAccountingPeriod.getFiscalYear())
            .eq(${classInfo.classAliasName}Model::getAccountingPeriod,lastAccountingPeriod.getAccountingPeriod());
        List<${classInfo.classAliasName}Model> lastPeriodList = getBaseMapper().selectList(wrapper);
        if(CollectionUtil.isEmpty(lastPeriodList)){
                throw new BaseBusinessException("上一周期暂无数据");
        }

        //获取上一期间的数据
        List<${classInfo.classAliasName}Model> insertList = new ArrayList<>();
            for (${classInfo.classAliasName}Model lastModel : lastPeriodList) {
            ${classInfo.classAliasName}Model model = new ${classInfo.classAliasName}Model();
            BeanUtils.copyProperties(lastModel, model);
            model.setId(UUIDUtils.nextString());
            model.setFiscalYear(fiscalYear);
            model.setAccountingPeriod(String.valueOf(accountingPeriod));
            insertList.add(model);
            }

            //删除本期间数据
            LambdaQueryWrapper<${classInfo.classAliasName}Model> delWrapper = Wrappers.lambdaQuery(${classInfo.classAliasName}Model.class);
                delWrapper.eq(${classInfo.classAliasName}Model::getFiscalYear, fiscalYear).eq(${classInfo.classAliasName}Model::getAccountingPeriod, accountingPeriod);
                remove(delWrapper);
                this.saveBatch(insertList);

   }


    /**
    * 根据会计期间获取 科研项目成本汇总表信息
    *
    * @param queryForm
    * @return List<${classInfo.classAliasName}Model>
    * @return void
    * @Date 9:22 2024/8/15
    * @since ${classInfo.version}
    */
        @Override 
     public List<${classInfo.classAliasName}Model> getListByPeriod(${classInfo.classAliasName}QueryForm queryForm) {
            return Collections.emptyList();
     }
                                                

                                 
}